﻿using MongoDB.Driver;
using Sustainalytics.Entities;
using Sustainalytics.ScreeningTool.Synchronization.Handlers;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Sustainalytics.ScreeningTool.Synchronization.Processors
{
    public class Processor<T> : IProcessor where T : IEntity
    {
        private readonly IMongoCollection<T> _collection;
        private readonly IHandler<T> _handler;

        public Processor(IMongoCollection<T> collection, IHandler<T> handler)
        {
            _collection = collection;
            _handler = handler;
        }

        public string CollectionName => _collection.CollectionNamespace.FullName;

        public async Task ForEachExtraElementsAsync(Func<IEnumerable<ExtraElement>, Guid, Task> processExtraElements)
        {
            await _collection
                .Find(GetFilter())
                .Project<T>(GetProjection())
                .ForEachAsync(async entity =>
                {
                    var extraElements = _handler.GetExtraElements(entity);
                    await processExtraElements.Invoke(extraElements, entity.Id).ConfigureAwait(false);
                }).ConfigureAwait(false);
        }

        protected virtual FilterDefinition<T> GetFilter()
            => Builders<T>.Filter.Empty;

        private ProjectionDefinition<T> GetProjection()
            => _handler.GetProjection(Builders<T>.Projection);
    }
}
